package bd403.Backend;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import bd403.namespace.BDActivity;
import bd403.namespace.R;
import bd403.utils.KeyboardSetup;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

/* UI and functionality for the Login page of the BrewDawg application.
 * Main author: Mike
 */

public class Login extends Activity {
	
	private final String URL_START = "http://cubist.cs.washington.edu/~jhl123/index.php?";
	private final String HTTP_USER_SUFFIX = "var1=getusers";
	private boolean valid;
	
    /* Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
		setContentView(R.layout.login);
	
        this.valid = false;
        setupKeyboard();
        final EditText userText = (EditText) findViewById(R.id.user);
        final EditText passText = (EditText) findViewById(R.id.password);
		
        // Initialize the listener for the 'Login' button
		Button login = (Button) findViewById(R.id.loginButton);
		login.setOnClickListener(new View.OnClickListener() {
	        public void onClick(View view) {
	        	if (userText.getText().toString().equals("") || passText.getText().toString().equals("")) {
	        		Toast.makeText(getApplicationContext(), getString(R.string.login_submiterr_blank), Toast.LENGTH_SHORT).show();
	        	} else if (!validChar(userText.getText().toString().toLowerCase())) {
	        		Toast.makeText(getApplicationContext(), getString(R.string.login_submiterr_name), Toast.LENGTH_SHORT).show();
	        	} else if (!validChar(passText.getText().toString().toLowerCase())) {
	        		Toast.makeText(getApplicationContext(), getString(R.string.login_submiterr_pass), Toast.LENGTH_SHORT).show();
	        	} else {
	        		if (hasConnection()) {
	        			bdSyncTask serverConnect = new bdSyncTask();
	        			serverConnect.execute(userText.getText().toString().toLowerCase(), passText.getText().toString().toLowerCase());
	        		} else {
	        			Toast.makeText(getApplicationContext(), getString(R.string.login_submiterr_noconn), Toast.LENGTH_SHORT).show();
	        		}
	        	}
	        };
		});
    }
    
    /* Initializes keyboard settings for login.
     */
    private void setupKeyboard() {
    	final EditText userText = (EditText) findViewById(R.id.user);
        final EditText passText = (EditText) findViewById(R.id.password);
    	
        KeyboardSetup ks = KeyboardSetup.getInstance(this);
    	// Changes enter key on soft keyboard to minimize keyboard
        ks.setupKeyboard(userText);
        ks.setupKeyboard(passText);
    }
    
    /* Accepts a user name and password as parameters, and returns true if the
     * user name and password are registered in the database. Otherwise returns false.
     */
    private boolean authenticate(String uname, String pass) {
    	String users = DrinkDB.httpConn(URL_START + HTTP_USER_SUFFIX);
    	if (users == null) {
    		return false;
    	}
    	JSONArray jArr;
		try {
			jArr = new JSONArray(users);
			JSONObject json_data = null;
			for (int i = 0; i < jArr.length(); i++) {
				json_data = jArr.getJSONObject(i);
				if (uname.equals(json_data.get("name").toString()) && pass.equals(json_data.get("pass").toString())) {
					return true;
				}
			}
		} catch (JSONException e) {
			return false;
		}
		return false;
    }
    
    /* Handler to switch to the registration page.
     */
    public void clickHandle(View v) {
    	startActivity(new Intent(getApplicationContext(), Registration.class));
    	finish();
    }
    
    /* Private helper class used to execute an asynchronous request to the server.
	 * Runs in the background while the main UI thread runs in the foreground.
	 */
	private class bdSyncTask extends AsyncTask<String, Void, Void> {
		private ProgressDialog dialog; // dialog to display while connecting to the server
		private String username;

		// Setup inpStream and parameters needed to execute the task prior to doing the work.
		@Override
		protected void onPreExecute() {
			dialog = ProgressDialog.show(Login.this, "", getString(R.string.login_auth), true, false);
		}

		// Task this thread will run in the background when the .execute() method is invoked.
		@Override
		protected Void doInBackground(String... param) {
			valid = authenticate(param[0], param[1]);
			username = param[0];
			return null;
		}

		// Executed after doInBackground has completed to compute final results
		protected void onPostExecute(Void arg1) {
			/* Dismiss 'Search' dialog */
			dialog.dismiss();
			
			// If login was valid, launch the app, otherwise display and error message
			if (valid) {
				DrinkStorage ds = (DrinkStorage)getApplicationContext();
				ds.initializeUser(username);
				startActivity(new Intent(getApplicationContext(), BDActivity.class));
				finish(); // prevent users from going back to the login page
			} else {
				Toast.makeText(getApplicationContext(), getString(R.string.login_fail), Toast.LENGTH_SHORT).show();
			}
		}
	}
	
	/* Returns true if this input String contains all legal characters. Otherwise returns false.
	 * Legal characters for input include all alphabetic characters.
	 */
	private boolean validChar(String input) {
		// a = 97, z = 122
		for (int i = 0; i < input.length(); i++) {
			if (input.charAt(i) < 'a' || input.charAt(i) > 'z') {
				return false;
			}
		}
		return true;
	}
	
	/* Returns true if an Internet connection is available, otherwise returns false.
	 */
	private boolean hasConnection() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
        return activeNetwork != null;
    }
}